#include <iostream>
#include <algorithm>
#include <map>
#include <vector>

#define $(x) make_pair(x, #x)

using namespace std;

namespace llib
{
    class lmonitor
    {
        private:
            map<string, vector<pair<void*, string>>> pairs;
        public:
            lmonitor();
            ~lmonitor();
            template <typename... T>
            void add(string tag, T...args);
            void print(string tag, int tab = 0);
            void clear(string tag);
    };
    
    lmonitor::lmonitor() { }
    lmonitor::~lmonitor() { }

    template <typename... T>
    void lmonitor::add(string tag, T...args)
    {
        if (pairs.find(tag) == pairs.end())
        {
            pairs.insert(make_pair(tag, vector<pair<void*, string>>()));
        }
        
        for (auto arg : {args...})
        {
            pairs[tag].push_back(arg);
        }
    }

    void lmonitor::print(string tag, int tab = 0)
    {
        if (pairs.find(tag) == pairs.end())
        {
            throw tag + "是无效的";
        }
        
        for (size_t i = 0; i < tab; i++)
        {
            cout << "\t";
        }
        
        for (auto arg : pairs[tag])
        {
            // cout << arg.second 
            //     << ":"
            //     << *(arg.first)
            //     << " ";
        }
        cout << "\n";
    }

    void lmonitor::clear(string tag)
    {
        pairs[tag] = vector<pair<void*, string>>();
    }

    template <typename... T>
    void printm(int tab, T... args)
    {
        for (size_t i = 0; i < tab; i++)
        {
            cout << "\t";
        }
        for (pair<void*, string> arg : {args...})
        {
            cout << arg.second
                << ":"
                << arg.first
                << " ";
        }
        cout << "\n";        
    }

    template <typename... T>
    void printm(T... args)
    {
        printm(0, args);
    }
}


int main(int argc, char const *argv[])
{
    llib::lmonitor monitor = llib::lmonitor();
    int i = 5;
    monitor.add("tag", $(i));
    monitor.print("tag");
    /* code */
    // cout << $(i).;
    return 0;
}
